package org.jspar;

import java.io.FileReader;
import java.util.List;

import org.jspar.io.NetListReader;
import org.jspar.matrix.ConnectionMatrix;
import org.jspar.model.Module;
import org.jspar.model.Net;
import org.jspar.model.NetList;
import org.jspar.model.Terminal;
import org.jspar.partition.Partitioning;
import org.jspar.place.Placement;
import org.jspar.tile.SVGExporter;


public class Main {

	public static void main(String[] args) throws Exception {

		Options conf = Options.getDefault();

		//NetList netList = new IVFParser().read(new FileReader("tests/add4.ivf"));
		NetList netList = new NetListReader().read(new FileReader("tests/SN7474.xml"));
		System.out.println(netList);

		ConnectionMatrix matrix = conf.getMatrixBuilder().build(netList);
		Partitioning partitioning = new Partitioning(conf, matrix, netList);
		List<Partition> partitions = partitioning.buildPartitions();
		eraseSysterms(netList, partitions);
		
		Placement placement = new Placement(conf, matrix, netList, partitions);
		Partition mainPartition = placement.run();

		dumpPartition(mainPartition, netList);
		
		/*Rectangle bounds = placement.getBounds();
		GlobalRouting grouting = new GlobalRouting(conf);
		grouting.createRoutingSpace(mainPartition.modules(), bounds, netList);
		grouting.firstGlobalRoute(mainPartition.modules(), true);
		*/
    }
	
	private static void dumpPartition(Partition p, NetList netList) {
		for (Module m : p.modules()) {
			System.out.println(m + " -> " + m.getBounds());
			for (Terminal t : m.terminals()) {
				System.out.println("  " + t.name() + " -> " + t.getPosition());
			}
		}
		for (Net n : netList.nets()) {
			System.out.println(n);
		}
	}

	private static void eraseSysterms(NetList netlist,
			List<Partition> partitions) {
		Partition outs = new Partition();
		Partition ins = new Partition();

		for (Module systerm : netlist.extMods()) {
			systerm.clearFlag(Module.PLACED);
			Partition old_part = systerm.partition();
			if (systerm.type().isOut()) {
				old_part.remove(systerm);
				outs.add(systerm);
			} else /* (systerm.type().equals("IN") || systerm.type().equals("INOUT")) */ {
				old_part.remove(systerm);
				ins.add(systerm);
			}
			if (old_part.size() == 0)
				partitions.remove(old_part);
		}
	}
    
}
